package question1;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.Properties;

public class ListeProxyHttp implements Liste<String>
{
	private final static String URL_ESIEE= "http://pc5357c.esiee.fr:8788/tests/tp_proxy.html";

	private Liste<String> liste;
	private String nom;
	private String url;

	public ListeProxyHttp( String nom )
	{
		this( URL_ESIEE, nom );
	}

	public ListeProxyHttp( String url, String nom )
	{
		this.liste= new ListeImpl( nom );
		this.url= url;
		this.nom= nom;
	}

	public boolean ajouter( String elt )
	{
		// a completer par une connexion HTTP avec les parametres suivants "nom=" + this.nom + "&commande=ajouter&elt="+ elt);
		// usage de la classe Connexion interne ci-dessous
		Connexion connexion = new Connexion(this.url,"nom=" + this.nom + "&commande=ajouter&elt="+ elt); 

		Boolean resultatLocal = liste.ajouter(elt);

		String resultatDistant = connexion.result();

		if(!resultatDistant.equals(resultatLocal.toString())){
			throw new CoherenceListeException("ajouter");
		}
		return resultatLocal;
	}

	public boolean retirer( String elt )
	{
		// a completer par une connexion HTTP avec les parametres suivants "nom=" + this.nom + "&commande=retirer&elt="+ elt
		Connexion connexion= new Connexion(this.url,"nom=" + this.nom + "&commande=retirer&elt="+ elt); // a completer 
		Boolean resultatLocal = liste.retirer(elt);

		String resultatDistant = connexion.result();

		if(!resultatLocal.equals(resultatDistant)){
			throw new CoherenceListeException("retirer");
		}
		return resultatLocal;
	}

	public boolean vider()
	{
		// a completer par une connexion HTTP avec les parametres suivants "nom=" + this.nom + "&commande=vider"
		Connexion connexion= new Connexion(this.url,"nom=" + this.nom + "&commande=vider"); // a completer 

		String resultatDistant = connexion.result();
		Boolean resultatLocal= liste.vider();

		if(!resultatLocal.equals(resultatDistant)){
			throw new CoherenceListeException("vider");
		}
		return resultatLocal;
	}

	public boolean restaurer()
	{
		Connexion connexion = null; // a completer 
		return false; // a completer 
	}

	public boolean estPresent( String elt )
	{
		Connexion connexion = new Connexion(this.url,"nom="+this.nom+"&commande=estPresent&elt="+elt);  
		String resultatDistant = connexion.result();
		Boolean resultatLocal= liste.estPresent(elt);

		if(!resultatLocal.equals(resultatDistant)){
			throw new CoherenceListeException("estPresent");
		}
		return resultatLocal;
	}

	public int taille()
	{
		Connexion connexion = new Connexion(this.url,"nom="+this.nom+"&commande=taille");  
		String resultatDistant = connexion.result();
		int resultatLocal= liste.taille();
		int parsedResult = Integer.parseInt(resultatDistant);

		if(resultatLocal != parsedResult){
			throw new CoherenceListeException("taille");
		}
		return resultatLocal;
	}

	public Iterator<String> iterator()
	{ // complete
		return liste.iterator();
	}

	public String toString()
	{
		Connexion connexion = new Connexion(this.url,"nom="+this.nom+"&commande=toString");  
		String resultatDistant = connexion.result();
		String resultatLocal= liste.toString();

		if(resultatLocal.equals(resultatDistant)){
			throw new CoherenceListeException("taille");
		}
		return resultatLocal;
	}

	/** Classe complete d'emission d'une requete au protocole HTTP
	 * 
	 */
	private static class Connexion extends Thread
	{
		private String url;
		private String parametres;
		private String result;

		public Connexion( String url )
		{
			this( url, null );
		}

		public Connexion( String url, String parametres )
		{
			this.url= url;
			this.parametres= parametres.trim();
			this.result= new String( "" );
			this.start();
		}

		public String result()
		{
			try {
				this.join();
			}
			catch ( InterruptedException ie ) {
				//ie.printStackTrace();
			}
			return result;
		}

		public void run()
		{
			try {
				URL urlConnection= new URL( url );
				URLConnection connection= urlConnection.openConnection();
				connection.setDoOutput( true );

				PrintWriter out= new PrintWriter( connection.getOutputStream() );
				out.println( parametres );
				out.flush();
				out.close();

				BufferedReader in= new BufferedReader( new InputStreamReader(
						connection.getInputStream() ) );
				String inputLine= in.readLine();
				while ( inputLine != null ) {
					result+= inputLine;
					inputLine= in.readLine();
				}
				in.close();
			}
			catch ( Exception e ) {
				this.result= "";
				//e.printStackTrace();
			}
		}
	}

	/** Mise en place du proxy si necessaire
	 *  attention, aucune verification de la validite de l'URL transmise n'est effectuee
	 *  en wifi au Cnam 
	 *  @param proxyHost adresse du proxy
	 *  @param proxyPort le port du proxy
	 */
	public static void setHttpProxy( String proxyHost, int proxyPort )
	{
		Properties prop= System.getProperties();
		prop.put( "proxySet", "true" );
		prop.put( "http.proxyHost", proxyHost );
		prop.put( "http.proxyPort", Integer.toString( proxyPort ) );
	}

}
